// MobileInfo.cpp : Defines the entry point for the application.
//

#include "MobileInfo.h"
#include <windows.h>
#include <aygshell.h>
#include <htmlctrl.h>
#include <regext.h>
#include <snapi.h>

// Read the specified string value out of the registry and
// append it in HTML form to the end of the string 'pszHTML'.
static void AppendStringProperty(LPTSTR pszHTML, HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValueName)
{
	TCHAR szBuffer[2048];

	HRESULT hr = RegistryGetString(hKey, pszSubKey, pszValueName, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
	if (hr != S_OK)
		szBuffer[0] = '\0';

	TCHAR szTemp[2048];
	_stprintf(szTemp, _T("'%s'<br/><br/>"), szBuffer);
	_tcscat(pszHTML, szTemp);
}

// Read the specified boolean value out of the registry and
// append it in HTML form to the end of the string 'pszHTML'.
static void AppendBooleanProperty(LPTSTR pszHTML, HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValueName, DWORD dwMask)
{
	DWORD dwValue;

	HRESULT hr = RegistryGetDWORD(hKey, pszSubKey, pszValueName, &dwValue);
	if (hr != S_OK)
		dwValue = 0;

	if (dwValue & dwMask)
	{
		_tcscat(pszHTML, _T("'true'<br/><br/>"));
	}
	else
	{
		_tcscat(pszHTML, _T("'false'<br/><br/>"));
	}
}

// Read the specified DWORD value out of the registry and
// append it in HTML form to the end of the string 'pszHTML'.
static void AppendDWORDProperty(LPTSTR pszHTML, HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValueName, DWORD dwMask)
{
	DWORD dwValue;

	HRESULT hr = RegistryGetDWORD(hKey, pszSubKey, pszValueName, &dwValue);
	if (hr != S_OK)
		dwValue = 0;

	TCHAR szTemp[32];
	_stprintf(szTemp, _T("'%d'<br /><br />"), dwValue & dwMask);
	_tcscat(pszHTML, szTemp);
}


static void QueryStateAndNotificationBroker(HWND hDlg)
{
	DWORD dwValue;
	static TCHAR szHTML[32 * 1024];

	_tcscpy(szHTML, _T("<b>Active Application:</b><br/>"));
	AppendStringProperty(szHTML, SN_ACTIVEAPPLICATION_ROOT,
		SN_ACTIVEAPPLICATION_PATH, SN_ACTIVEAPPLICATION_VALUE);

    _tcscat(szHTML, _T("<b>Active Sync Status</b><br/>"));
    AppendStringProperty(szHTML, SN_ACTIVESYNCSTATUS_ROOT,
		SN_ACTIVESYNCSTATUS_PATH, SN_ACTIVESYNCSTATUS_VALUE);

#if _WIN32_WCE >= 0x502 // Requires Windows Mobile 6.0 or greater
    _tcscat(szHTML, _T("<b>Bluetooth State Hardware Present</b><br/>"));
	AppendBooleanProperty(szHTML, SN_BLUETOOTHSTATEHARDWAREPRESENT_ROOT,
		SN_BLUETOOTHSTATEHARDWAREPRESENT_PATH, SN_BLUETOOTHSTATEHARDWAREPRESENT_VALUE,
		SN_BLUETOOTHSTATEHARDWAREPRESENT_BITMASK);

    _tcscat(szHTML, _T("<b>Bluetooth State Power On</b><br/>"));
    AppendBooleanProperty(szHTML, SN_BLUETOOTHSTATEPOWERON_ROOT,
		SN_BLUETOOTHSTATEPOWERON_PATH, SN_BLUETOOTHSTATEPOWERON_VALUE,
		SN_BLUETOOTHSTATEPOWERON_BITMASK);

    _tcscat(szHTML, _T("<b>Camera Enabled</b><br/>"));
	AppendBooleanProperty(szHTML, SN_CAMERAENABLED_ROOT,
		SN_CAMERAENABLED_PATH, SN_CAMERAENABLED_VALUE, MAXDWORD);
#endif

    _tcscat(szHTML, _T("<b>CameraPresent</b><br/>"));
	AppendBooleanProperty(szHTML, SN_CAMERAPRESENT_ROOT,
		SN_CAMERAPRESENT_PATH, SN_CAMERAPRESENT_VALUE, MAXDWORD);

    _tcscat(szHTML, _T("<b>Connections Bluetooth Descriptions</b><br/>"));
    AppendStringProperty(szHTML, SN_CONNECTIONSBLUETOOTHCOUNT_ROOT,
		SN_CONNECTIONSBLUETOOTHCOUNT_PATH, SN_CONNECTIONSBLUETOOTHCOUNT_VALUE);

    _tcscat(szHTML, _T("<b>Connections Cellular Descriptions</b><br/>"));
    AppendStringProperty(szHTML, SN_CONNECTIONSCELLULARDESCRIPTIONS_ROOT,
		SN_CONNECTIONSCELLULARDESCRIPTIONS_PATH, SN_CONNECTIONSCELLULARDESCRIPTIONS_VALUE);

    _tcscat(szHTML, _T("<b>Cradle Present</b><br/>"));
	AppendBooleanProperty(szHTML, SN_CRADLEPRESENT_ROOT,
		SN_CRADLEPRESENT_PATH, SN_CRADLEPRESENT_VALUE, MAXDWORD);

	_tcscat(szHTML, _T("<b>Display Rotation</b><br/>"));
	AppendDWORDProperty(szHTML, SN_DISPLAYROTATION_ROOT,
		SN_DISPLAYROTATION_PATH, SN_DISPLAYROTATION_VALUE, MAXDWORD);

    _tcscat(szHTML, _T("<b>Owner Email</b><br/>"));
	AppendStringProperty(szHTML, SN_OWNEREMAIL_ROOT,
		SN_OWNEREMAIL_PATH, SN_OWNEREMAIL_VALUE);

    _tcscat(szHTML, _T("<b>Owner Name</b><br/>"));
	AppendStringProperty(szHTML, SN_OWNERNAME_ROOT,
		SN_OWNERNAME_PATH, SN_OWNERNAME_VALUE);

    _tcscat(szHTML, _T("<b>Owner Phone Number</b><br/>"));
	AppendStringProperty(szHTML, SN_OWNERPHONENUMBER_ROOT,
		SN_OWNERPHONENUMBER_PATH, SN_OWNERPHONENUMBER_VALUE);

    _tcscat(szHTML, _T("<b>Phone Sound Profile</b><br/>"));
	AppendStringProperty(szHTML, SN_PHONEPROFILE_ROOT,
		SN_PHONEPROFILE_PATH, SN_PHONEPROFILE_VALUE);

    _tcscat(szHTML, _T("<b>Phone Roaming</b><br/>"));
	AppendBooleanProperty(szHTML, SN_PHONEROAMING_ROOT,
		SN_PHONEROAMING_PATH, SN_PHONEROAMING_VALUE,
		SN_PHONEROAMING_BITMASK);

    _tcscat(szHTML, _T("<b>Phone Signal Strength</b><br/>"));
	AppendDWORDProperty(szHTML, SN_PHONESIGNALSTRENGTH_ROOT,
		SN_PHONESIGNALSTRENGTH_PATH, SN_PHONESIGNALSTRENGTH_VALUE, MAXDWORD);

    _tcscat(szHTML, _T("<b>Power Battery State</b><br/>"));
	dwValue = 0;
	if (RegistryGetDWORD(SN_POWERBATTERYSTATE_ROOT,
		SN_POWERBATTERYSTATE_PATH, SN_POWERBATTERYSTATE_VALUE, &dwValue) != S_OK)
		dwValue = 0;
	dwValue &= SN_POWERBATTERYSTATE_BITMASK;

	if (dwValue == 0)
	{
		_tcscat(szHTML, _T("Normal"));
	}
	else
	{
		// Check each bit; specific battery drivers may set different combinations of bits.
		if (dwValue & 1)
			_tcscat(szHTML, _T("Not Present "));

		if (dwValue & 2)
			_tcscat(szHTML, _T("Charging "));

		if (dwValue & 4)
			_tcscat(szHTML, _T("Low "));
    
		if (dwValue & 8)
			_tcscat(szHTML, _T("Critical "));
    }
	_tcscat(szHTML, _T("<br/><br/>"));

    _tcscat(szHTML, _T("<b>Power Battery Strength</b><br/>"));
	dwValue = 0;
	if (RegistryGetDWORD(SN_POWERBATTERYSTRENGTH_ROOT,
		SN_POWERBATTERYSTRENGTH_PATH, SN_POWERBATTERYSTRENGTH_VALUE, &dwValue) != S_OK)
		dwValue = 0;
	dwValue = (dwValue & SN_POWERBATTERYSTRENGTH_BITMASK) >> 16;

    if (dwValue >= 81)
    {
      _tcscat(szHTML, _T("Very High"));
	}
	else if (dwValue >= 61)
    {
      _tcscat(szHTML, _T("High"));
    }
	else if (dwValue >= 41)
    {
      _tcscat(szHTML, _T("Medium"));
    }
	else if (dwValue >= 21)
    {
      _tcscat(szHTML, _T("Low"));
    }
	else 
    {
      _tcscat(szHTML, _T("Very Low"));
    }
	_tcscat(szHTML, _T("<br/><br/>"));

    _tcscat(szHTML, _T("<b>Connections Count</b><br/>"));
	AppendDWORDProperty(szHTML, SN_CONNECTIONSCOUNT_ROOT,
		SN_CONNECTIONSCOUNT_PATH, SN_CONNECTIONSCOUNT_VALUE,
		MAXDWORD);

#if _WIN32_WCE >= 0x502 // Requires Windows Mobile 6.0 or greater
    _tcscat(szHTML, _T("<b>WiFi State Connected</b><br/>"));
	AppendBooleanProperty(szHTML, SN_WIFISTATECONNECTED_ROOT,
		SN_WIFISTATECONNECTED_PATH, SN_WIFISTATECONNECTED_VALUE,
		SN_WIFISTATECONNECTED_BITMASK);
#endif

	SendDlgItemMessage(hDlg, IDC_HTMLVIEW, DTM_ADDTEXTW, 0, (LPARAM)szHTML);
	SendDlgItemMessage(hDlg, IDC_HTMLVIEW, DTM_ENDOFSOURCE, 0, 0);
}

// Message handler for Mobile Info dialog
INT_PTR CALLBACK MobileInfoDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);

				// Create a menu bar
				SHMENUBARINFO mbi;
                memset(&mbi, 0, sizeof(SHMENUBARINFO));
				mbi.cbSize     = sizeof(SHMENUBARINFO);
				mbi.hwndParent = hDlg;
				mbi.nToolBarId = IDR_MENU;
				mbi.hInstRes   = GetModuleHandle(NULL);
				mbi.dwFlags = SHCMBF_HMENU | SHCMBF_HIDESIPBUTTON;
	            SHCreateMenuBar(&mbi);

				// Set focus to the HTML view (otherwise smartphone
				// devices have no way to select it to scroll down)
				SetFocus(GetDlgItem(hDlg, IDC_HTMLVIEW));

				// Kick off a refresh of the SNAPI properties
				PostMessage(hDlg, WM_COMMAND, IDC_REFRESH, 0);
            }
            return (INT_PTR)TRUE;

		case WM_SIZE:
			{
				// Resize the HTML control to cover the entire
				// client area
				HWND hwndHTML = GetDlgItem(hDlg, IDC_HTMLVIEW);
				SetWindowPos(hwndHTML, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER);
			}
			break;

        case WM_COMMAND:
			switch (LOWORD(wParam))
			{
			case IDC_REFRESH:
				QueryStateAndNotificationBroker(hDlg);
				break;

			case IDOK:
                EndDialog(hDlg, LOWORD(wParam));
                return (INT_PTR)TRUE;
			}
            break;

        case WM_CLOSE:
            EndDialog(hDlg, message);
            return (INT_PTR)TRUE;

    }
    return (INT_PTR)FALSE;
}

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
	InitHTMLControl(hInstance);

	return DialogBox(hInstance, (LPCTSTR)IDD_MOBILEINFO, NULL, MobileInfoDialog);
}